<html>
<head><meta charset="utf-8"><title>surprising borrow checker behavior · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html">surprising borrow checker behavior</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="203602371"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203602371" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Renshaw <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203602371">(Jul 11 2020 at 15:59)</a>:</h4>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=ec573600fbfee22498b02f9af4894632">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=ec573600fbfee22498b02f9af4894632</a></p>



<a name="203602445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203602445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203602445">(Jul 11 2020 at 16:00)</a>:</h4>
<p>Presumably since <code>W</code> is early-bound, but the elided lifetime parameters are late-bound?</p>



<a name="203602464"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203602464" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Renshaw <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203602464">(Jul 11 2020 at 16:01)</a>:</h4>
<p>interesting</p>



<a name="203602564"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203602564" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Renshaw <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203602564">(Jul 11 2020 at 16:02)</a>:</h4>
<p>Is there any way to make the lifetime late-bound without declaring wrapper functions?</p>



<a name="203605541"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203605541" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Renshaw <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203605541">(Jul 11 2020 at 17:23)</a>:</h4>
<p>I want to be able to add a type annotation to <code>do_write</code>. It seems like the missing piece I would need is a lifetime-level lambda.</p>



<a name="203605602"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203605602" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Renshaw <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203605602">(Jul 11 2020 at 17:24)</a>:</h4>
<p>something like</p>
<div class="codehilite"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">do_write</span>: <span class="nc">for</span><span class="o">&lt;</span><span class="na">&#39;r</span><span class="p">,</span><span class="w"> </span><span class="na">&#39;s</span><span class="o">&gt;</span><span class="w"> </span><span class="k">fn</span><span class="p">(</span><span class="o">&amp;</span><span class="na">&#39;r</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">O</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="na">&#39;s</span><span class="w"> </span><span class="kt">str</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"></span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="n">packed</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">&lt;</span><span class="na">&#39;t</span><span class="o">&gt;</span><span class="w"> </span><span class="n">write_message_packed</span>::<span class="o">&lt;&amp;</span><span class="na">&#39;t</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">O</span><span class="o">&gt;</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">&lt;</span><span class="na">&#39;t</span><span class="o">&gt;</span><span class="w"> </span><span class="n">write_message</span>::<span class="o">&lt;&amp;</span><span class="na">&#39;t</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">O</span><span class="o">&gt;</span><span class="w"></span>
<span class="p">};</span><span class="w"></span>
</code></pre></div>



<a name="203605607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203605607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> David Renshaw <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203605607">(Jul 11 2020 at 17:25)</a>:</h4>
<p>where that  <code>&lt;'t&gt;</code> is fake syntax and what I mean by "lifetime-level lambda"</p>



<a name="203626234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626234">(Jul 12 2020 at 03:54)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> ^^ remember when I was suggesting we remove the early/late-bound distinction (or even early parameterization of functions by type parameters etc.), by having a binder around the substs of a function in <code>ty::FnDef</code>?</p>



<a name="203626243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626243">(Jul 12 2020 at 03:54)</a>:</h4>
<p>(I don't really want explicit syntax if we can avoid it)</p>



<a name="203626254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626254">(Jul 12 2020 at 03:55)</a>:</h4>
<p>as usual, inference backwards compatibility makes me sad</p>



<a name="203626263"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626263" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626263">(Jul 12 2020 at 03:55)</a>:</h4>
<p>since I bet some crates have abused <code>let f = generic_function;</code> and then using <code>f</code> multiple times, to guide inference</p>



<a name="203626386"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626386" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626386">(Jul 12 2020 at 03:59)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> but it should be possible to at least infer more interesting types for <code>ty::FnDef</code>, than today, if we do add a binder</p>



<a name="203626457"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626457" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626457">(Jul 12 2020 at 04:01)</a>:</h4>
<p>all lifetime parameters not explicitly specified could be handled as bound to the <code>ty::FnDef</code> and I guess at least that shouldn't cause inference problems. and <code>for&lt;...&gt; fn(...)</code> / <code>impl for&lt;...&gt; Fn(...)</code> hints could, just like they do today with closures, introduce <code>for&lt;...&gt;</code></p>



<a name="203626460"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626460" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626460">(Jul 12 2020 at 04:01)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> effectively making <code>path::to::function</code> equivalent to <code>|a, b, c| path::to::function(a, b, c)</code></p>



<a name="203626531"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626531" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626531">(Jul 12 2020 at 04:04)</a>:</h4>
<p><span class="user-mention" data-user-id="258831">@David Renshaw</span> at least you don't need wrapper functions, just closures <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=a8125e473d8d25ae6da57cc13f8ff03d">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=a8125e473d8d25ae6da57cc13f8ff03d</a></p>



<a name="203626560"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626560" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626560">(Jul 12 2020 at 04:05)</a>:</h4>
<p>note that this doesn't work w/o the hint</p>



<a name="203626675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626675">(Jul 12 2020 at 04:08)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> hmm, actually, there is something we could do backwards-compatibly, but it's weird? we can skolemize <code>f</code> (from <code>let f = path::to::function;</code>) <em>only</em> wrt lifetimes, so that every time it's called they can be different, but infer a fixed type "skeleton" otherwise</p>



<a name="203626744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626744">(Jul 12 2020 at 04:11)</a>:</h4>
<p>the problem with that is that e.g. calling the function with <code>&amp;'x mut Foo&lt;'y&gt;</code> could result in <code>path::to::function::&lt;_&gt;</code> becoming <code>for&lt;'a, 'b&gt; path::to::function::&lt;&amp;'a mut Foo&lt;'b&gt;&gt;</code> and I doubt that kind of binder injection is at all possible today, without making the entire <code>ty::FnDef</code> actually an inference variable</p>



<a name="203626752"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/surprising%20borrow%20checker%20behavior/near/203626752" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/surprising.20borrow.20checker.20behavior.html#203626752">(Jul 12 2020 at 04:11)</a>:</h4>
<p>anyway this is all random ranting</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>